#ifndef UDPSYS_H
#define UDPSYS_H

#define MAX_DEVICES         100
#define PORT_UDP_COMM_1         3444        // UDP端口1
#define PORT_UDP_COMM_2         4555        // UDP端口2
#define PORT_TCP_COMM_1         5666        // TCP端口1

/* CMD 服务端<->客户端命令状态 */
#define CMD_STATUS  0xA1        //服务端<-->客户端    用于使客户端刷新主机状态  / 客户端返回本机mac地址列表（前两个），CPU/MEM占用率，CPU温度
#define CMD_RUNCMD  0xA2        //服务端<-->客户端    用于使客户端执行命令 / 客户端返回命令执行后的输出值
#define CMD_OUTCMD  0xA3        //服务端<---客户端    用户客户端通知服务端，命令运行超时
#define CMD_ENDCMD  0xA4        //服务端<---客户端    用户客户端通知服务端，命令运行结束
#define CMD_ERREND  0xA5        //服务端<---客户端    用户客户端通知服务端，命令运行异常结束结束
#define CMD_KILLALL 0xA6        //服务端--->客户端

/* 设备状态 */
#define STAT_STOPED                 (6)         //设备被手动停止测试
#define STAT_DISABLED               (5)         //设备被删除
#define STAT_STOP                   (4)         //设备被手动停止测试
#define STAT_DISABLE                (3)         //设备被删除
#define STAT_RESTART                (2)         //设备重启测试
#define STAT_RESTARTED              (1)         //设备重启测试中...
#define STAT_NORMAL                 (0)         //正常状态
#define STAT_ERR_CMD                (-1)        //执行命令，出错/超时无响应
#define STAT_ERR_TIMEOUT            (-2)        //命令执行时间超出预期过多
#define STAT_ERR_RESET_POWEROFF     (-3)        //关机失败
#define STAT_ERR_RESET_POWERON      (-4)        //开机失败
#define STAT_OFFLINE                (-5)        //设备掉线

#include <QString>
#include <QDateTime>
#include <QStringList>
class QUdpSocket;
class QTcpSocket;
class QHostAddress;

struct UdpDevice{
    unsigned long lastOnlineTime;   // 上次在线状态刷新时间，用于判断超时、掉线、重启
    unsigned long startTestTime;    // 本次测试开始时间，如一个命令有多次测试，该值存第一次启动时间
    unsigned long startCmdTime;     // 本次命令开始时间，用于判断命令是否执行超时
    int  status;                    // 状态标指，为0则正常
    int cmdIndex;                   // 测试命令index
    int testCounts;                 // 测试计数：单个命令
    int cpuRate;                    // CPU占用率，0~1000 ：0~100%
    int memRate;                    // MEM占用率，0~1000 ：0~100%
    int cpuTemp;                    // CPU温度，-1000~1000 ：-100.0~100.0
    bool isRuning;                  // 是否在执行测试命令
    bool isTestEnded;               // 测试是否结束
    bool isReboot;                  // 该测试命令是否为reboot
    bool isRebooted;                // 是否执行过了重启
    QString ipAddress;
    QString mac1;
    QString mac2;
    QString macStr;
    QString cmdOutStr;              // 本次测试命令返回值
    QStringList cmdResult;          // 所有测试结果
    QList<int>  testTimes;          // 保存每次测试用掉的总时间
    int         testTotalUseTimes;  // 测试当前用掉的时间，测试总的超时时间，用于计算测试进度
    int         testTotalCounts;    // 测试了命令总的组测试数，用于计算测试进度
    QByteArray  leftPack;           // 拆包剩余的不完整的报文
    QString     testLogs;           // 测试日志
};

class UdpSys
{
public:
    UdpSys() {}
    static QStringList getLocalMacAddress();

    static int getOrder(const QByteArray &datagram);                // 返回命令码
    static QString getCmdStr(const QByteArray &datagram);           // 返回要执行的命令
    static QString getCmdOUtstr(const QByteArray &datagram);       // 返回执行命令的反馈值
    static int getLeftStrLen(const QByteArray &datagram);          // 在命令合并的情况下，获取剩余命令的长度
    static bool isCompletePack(const QByteArray &datagram);         // 检测是否是完整包
    static int getTimes(const QByteArray &datagram);                // 返回命令的时间
    static QString getDataRecvShow(const QByteArray &datagram);
    static QString getHostIP(const QHostAddress &hostAddress);
    static void getDevStatus(const QByteArray &datagram, int &cpuRate, int &memRate, int &cpuTemp, int &vdoTemp, int &hddTemp);

    static void sendDataGram_toAddress(QUdpSocket *udpSocket, int comm_port, QString address, int cmdID, int timeOuts, QString cmdStr, QString outStr);
    static bool sendDataGram_toAddress(QTcpSocket *tcpSocket, QString address, int cmdID, int timeOuts, QString cmdStr, QString outStr);
    static void sendDevState_toAddress(QUdpSocket *udpSocket, int comm_port, QString address, int cpuRate, int memRate, int cpuTemp, QString outStr);
    static bool sendDevState_toAddress(QTcpSocket *tcpSocket, QString address, int cpuRate, int memRate, int cpuTemp, QString outStr);
};

extern bool isStartTestCase;           //是否开始测试

#endif // MAIN_H
